home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / lisp / wgdb-42.lha / wgdb-4.2 / gdb / gmalloc.c < prev    next >
C/C++ Source or Header  |  1992-09-11  |  33KB  |  1,155 lines

  1.  
  2. /* gmalloc.c - THIS FILE IS AUTOMAGICALLY GENERATED SO DON'T EDIT IT. */
  3.  
  4. /* Single-file skeleton for GNU malloc.
  5.    Copyright 1989 Free Software Foundation
  6.           Written May 1989 by Mike Haertel.
  7.  
  8.    The author may be reached (Email) at the address mike@ai.mit.edu,
  9.    or (US mail) as Mike Haertel c/o Free Software Foundation.
  10.  
  11. This program is free software; you can redistribute it and/or modify
  12. it under the terms of the GNU General Public License as published by
  13. the Free Software Foundation; either version 2 of the License, or
  14. (at your option) any later version.
  15.  
  16. This program is distributed in the hope that it will be useful,
  17. but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19. GNU General Public License for more details.
  20.  
  21. You should have received a copy of the GNU General Public License
  22. along with this program; if not, write to the Free Software
  23. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  24.  
  25. #define __ONEFILE
  26.  
  27. /* DO NOT DELETE THIS LINE -- ansidecl.h INSERTED HERE. */
  28. /* Copyright (C) 1989 Free Software Foundation, Inc.
  29. This file is part of the GNU C Library.
  30.  
  31. This program is free software; you can redistribute it and/or modify
  32. it under the terms of the GNU General Public License as published by
  33. the Free Software Foundation; either version 2 of the License, or
  34. (at your option) any later version.
  35.  
  36. This program is distributed in the hope that it will be useful,
  37. but WITHOUT ANY WARRANTY; without even the implied warranty of
  38. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  39. GNU General Public License for more details.
  40.  
  41. You should have received a copy of the GNU General Public License
  42. along with this program; if not, write to the Free Software
  43. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  44.  
  45. /* ANSI and traditional C compatibility macros
  46.  
  47.    ANSI C is assumed if __STDC__ is #defined.
  48.  
  49.     Macros
  50.         PTR        - Generic pointer type
  51.         LONG_DOUBLE    - `long double' type
  52.         CONST        - `const' keyword
  53.         VOLATILE    - `volatile' keyword
  54.         SIGNED        - `signed' keyword
  55.         PTRCONST    - Generic const pointer (void *const)
  56.  
  57.     EXFUN(name, prototype)        - declare external function NAME
  58.                       with prototype PROTOTYPE
  59.     DEFUN(name, arglist, args)    - define function NAME with
  60.                       args ARGLIST of types in ARGS
  61.     DEFUN_VOID(name)        - define function NAME with no args
  62.     AND                - argument separator for ARGS
  63.     NOARGS                - null arglist
  64.     DOTS                - `...' in args
  65.  
  66.     For example:
  67.     extern int EXFUN(printf, (CONST char *format DOTS));
  68.     int DEFUN(fprintf, (stream, format),
  69.           FILE *stream AND CONST char *format DOTS) { ... }
  70.     void DEFUN_VOID(abort) { ... }
  71. */
  72.  
  73. #ifndef    _ANSIDECL_H
  74.  
  75. #define    _ANSIDECL_H    1
  76.  
  77.  
  78. /* Every source file includes this file,
  79.    so they will all get the switch for lint.  */
  80. /* LINTLIBRARY */
  81.  
  82.  
  83. #ifdef    __STDC__
  84.  
  85. #define    PTR        void *
  86. #define    PTRCONST    void *CONST
  87. #define    LONG_DOUBLE    long double
  88.  
  89. #define    AND        ,
  90. #define    NOARGS        void
  91. #define    CONST        const
  92. #define    VOLATILE    volatile
  93. #define    SIGNED        signed
  94. #define    DOTS        , ...
  95.  
  96. #define    EXFUN(name, proto)        name proto
  97. #define    DEFUN(name, arglist, args)    name(args)
  98. #define    DEFUN_VOID(name)        name(NOARGS)
  99.  
  100. #else    /* Not ANSI C.  */
  101.  
  102. #define    PTR        char *
  103. #define    PTRCONST    PTR
  104. #define    LONG_DOUBLE    double
  105.  
  106. #define    AND        ;
  107. #define    NOARGS
  108. #define    CONST
  109. #define    VOLATILE
  110. #define    SIGNED
  111. #define    DOTS
  112.  
  113. #define    EXFUN(name, proto)        name()
  114. #define    DEFUN(name, arglist, args)    name arglist args;
  115. #define    DEFUN_VOID(name)        name()
  116.  
  117. #endif    /* ANSI C.  */
  118.  
  119.  
  120. #endif    /* ansidecl.h    */
  121.  
  122. #ifdef __STDC__
  123. #include <limits.h>
  124. #else
  125. /* DO NOT DELETE THIS LINE -- limits.h INSERTED HERE. */
  126. /* Number of bits in a `char'.  */
  127. #define CHAR_BIT 8
  128.  
  129. /* No multibyte characters supported yet.  */
  130. #define MB_LEN_MAX 1
  131.  
  132. /* Minimum and maximum values a `signed char' can hold.  */
  133. #define SCHAR_MIN -128
  134. #define SCHAR_MAX 127
  135.  
  136. /* Maximum value an `unsigned char' can hold.  (Minimum is 0).  */
  137. #define UCHAR_MAX 255U
  138.  
  139. /* Minimum and maximum values a `char' can hold.  */
  140. #ifdef __CHAR_UNSIGNED__
  141. #define CHAR_MIN 0
  142. #define CHAR_MAX 255U
  143. #else
  144. #define CHAR_MIN -128
  145. #define CHAR_MAX 127
  146. #endif
  147.  
  148. /* Minimum and maximum values a `signed short int' can hold.  */
  149. #define SHRT_MIN -32768
  150. #define SHRT_MAX 32767
  151.  
  152. /* Maximum value an `unsigned short int' can hold.  (Minimum is 0).  */
  153. #define USHRT_MAX 65535U
  154.  
  155. /* Minimum and maximum values a `signed int' can hold.  */
  156. #define INT_MIN -2147483648
  157. #define INT_MAX 2147483647
  158.  
  159. /* Maximum value an `unsigned int' can hold.  (Minimum is 0).  */
  160. #define UINT_MAX 4294967295U
  161.  
  162. /* Minimum and maximum values a `signed long int' can hold.
  163.    (Same as `int').  */
  164. #define LONG_MIN (-LONG_MAX-1)
  165. #define LONG_MAX 2147483647
  166.  
  167. /* Maximum value an `unsigned long int' can hold.  (Minimum is 0).  */
  168. #define ULONG_MAX 4294967295U
  169. #endif
  170.  
  171. #ifdef __STDC__
  172. #include <stddef.h>
  173. #else
  174. /* DO NOT DELETE THIS LINE -- stddef.h INSERTED HERE. */
  175. #ifndef _STDDEF_H
  176. #define _STDDEF_H
  177.  
  178. /* Signed type of difference of two pointers.  */
  179.  
  180. typedef long ptrdiff_t;
  181.  
  182. /* Unsigned type of `sizeof' something.  */
  183.  
  184. #ifndef _SIZE_T    /* in case <sys/types.h> has defined it. */
  185. #define _SIZE_T
  186. typedef unsigned long size_t;
  187. #endif /* _SIZE_T */
  188.  
  189. /* A null pointer constant.  */
  190.  
  191. #undef NULL        /* in case <stdio.h> has defined it. */
  192. #define NULL 0
  193.  
  194. /* Offset of member MEMBER in a struct of type TYPE.  */
  195.  
  196. #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
  197.  
  198. #endif /* _STDDEF_H */
  199. #endif
  200.  
  201. /* DO NOT DELETE THIS LINE -- stdlib.h INSERTED HERE. */
  202. /* Fake stdlib.h supplying the stuff needed by malloc. */
  203.  
  204. #ifndef __ONEFILE
  205. #include <stddef.h>
  206. #endif
  207.  
  208. extern void EXFUN(abort, (void));
  209. extern void EXFUN(free, (PTR));
  210. extern PTR EXFUN(malloc, (size_t));
  211. extern PTR EXFUN(realloc, (PTR, size_t));
  212.  
  213. /* DO NOT DELETE THIS LINE -- string.h INSERTED HERE. */
  214. /* Fake string.h supplying stuff used by malloc. */
  215. #ifndef __ONEFILE
  216. #include <stddef.h>
  217. #endif
  218.  
  219. extern PTR EXFUN(memcpy, (PTR, PTR, size_t));
  220. extern PTR EXFUN(memset, (PTR, int, size_t));
  221. #define memmove memcpy
  222.  
  223. #define _MALLOC_INTERNAL
  224. /* DO NOT DELETE THIS LINE -- malloc.h INSERTED HERE. */
  225. /* Declarations for `malloc' and friends.
  226.    Copyright 1990 Free Software Foundation
  227.           Written May 1989 by Mike Haertel.
  228.  
  229.    The author may be reached (Email) at the address mike@ai.mit.edu,
  230.    or (US mail) as Mike Haertel c/o Free Software Foundation.
  231.  
  232. This program is free software; you can redistribute it and/or modify
  233. it under the terms of the GNU General Public License as published by
  234. the Free Software Foundation; either version 2 of the License, or
  235. (at your option) any later version.
  236.  
  237. This program is distributed in the hope that it will be useful,
  238. but WITHOUT ANY WARRANTY; without even the implied warranty of
  239. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  240. GNU General Public License for more details.
  241.  
  242. You should have received a copy of the GNU General Public License
  243. along with this program; if not, write to the Free Software
  244. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  245.  
  246. #ifndef _MALLOC_H
  247.  
  248. #define _MALLOC_H    1
  249.  
  250. #ifndef __ONEFILE
  251. #define    __need_NULL
  252. #define    __need_size_t
  253. #define __need_ptrdiff_t
  254. #include <stddef.h>
  255. #endif
  256.  
  257. #ifdef _MALLOC_INTERNAL
  258.  
  259. #ifndef __ONEFILE
  260. #include <limits.h>
  261. #endif
  262.  
  263. /* The allocator divides the heap into blocks of fixed size; large
  264.    requests receive one or more whole blocks, and small requests
  265.    receive a fragment of a block.  Fragment sizes are powers of two,
  266.    and all fragments of a block are the same size.  When all the
  267.    fragments in a block have been freed, the block itself is freed.  */
  268. #define INT_BIT        (CHAR_BIT * sizeof(int))
  269. #define BLOCKLOG    (INT_BIT > 16 ? 12 : 9)
  270. #define BLOCKSIZE    (1 << BLOCKLOG)
  271. #define BLOCKIFY(SIZE)    (((SIZE) + BLOCKSIZE - 1) / BLOCKSIZE)
  272.  
  273. /* Determine the amount of memory spanned by the initial heap table
  274.    (not an absolute limit).  */
  275. #define HEAP        (INT_BIT > 16 ? 4194304 : 65536)
  276.  
  277. /* Number of contiguous free blocks allowed to build up at the end of
  278.    memory before they will be returned to the system.  */
  279. #define FINAL_FREE_BLOCKS    8
  280.  
  281. /* Where to start searching the free list when looking for new memory.
  282.    The two possible values are 0 and _heapindex.  Starting at 0 seems
  283.    to reduce total memory usage, while starting at _heapindex seems to
  284.    run faster.  */
  285. #define MALLOC_SEARCH_START    _heapindex
  286.  
  287. /* Data structure giving per-block information.  */
  288. typedef union
  289.   {
  290.     /* Heap information for a busy block.  */
  291.     struct
  292.       {
  293.     /* Zero for a large block, or positive giving the
  294.        logarithm to the base two of the fragment size.  */
  295.     int type;
  296.     union
  297.       {
  298.         struct
  299.           {
  300.         size_t nfree;    /* Free fragments in a fragmented block.  */
  301.         size_t first;    /* First free fragment of the block.  */
  302.           } frag;
  303.         /* Size (in blocks) of a large cluster.  */
  304.         size_t size;
  305.       } info;
  306.       } busy;
  307.     /* Heap information for a free block (that may be the first of
  308.        a free cluster).  */
  309.     struct
  310.       {
  311.     size_t size;        /* Size (in blocks) of a free cluster.  */
  312.     size_t next;        /* Index of next free cluster.  */
  313.     size_t prev;        /* Index of previous free cluster.  */
  314.       } free;
  315.   } malloc_info;
  316.  
  317. /* Pointer to first block of the heap.  */
  318. extern char *_heapbase;
  319.  
  320. /* Table indexed by block number giving per-block information.  */
  321. extern malloc_info *_heapinfo;
  322.  
  323. /* Address to block number and vice versa.  */
  324. #define BLOCK(A) (((char *) (A) - _heapbase) / BLOCKSIZE + 1)
  325. #define ADDRESS(B) ((PTR) (((B) - 1) * BLOCKSIZE + _heapbase))
  326.  
  327. /* Current search index for the heap table.  */
  328. extern size_t _heapindex;
  329.  
  330. /* Limit of valid info table indices.  */
  331. extern size_t _heaplimit;
  332.  
  333. /* Doubly linked lists of free fragments.  */
  334. struct list
  335.   {
  336.     struct list *next;
  337.     struct list *prev;
  338.   };
  339.  
  340. /* Free list headers for each fragment size.  */
  341. extern struct list _fraghead[];
  342.  
  343. /* Instrumentation.  */
  344. extern size_t _chunks_used;
  345. extern size_t _bytes_used;
  346. extern size_t _chunks_free;
  347. extern size_t _bytes_free;
  348.  
  349. /* Internal version of free() used in morecore(). */
  350. extern void EXFUN(__free, (PTR __ptr));
  351.  
  352. #endif  /* _MALLOC_INTERNAL.  */
  353.  
  354. /* Underlying allocation function; successive calls should
  355.    return contiguous pieces of memory.  */
  356. extern PTR EXFUN((*__morecore), (ptrdiff_t __size));
  357.  
  358. /* Default value of previous.  */
  359. extern PTR EXFUN(__default_morecore, (ptrdiff_t __size));
  360.  
  361. /* Flag whether malloc has been called.  */
  362. extern int __malloc_initialized;
  363.  
  364. /* Hooks for debugging versions.  */
  365. extern void EXFUN((*__free_hook), (PTR __ptr));
  366. extern PTR EXFUN((*__malloc_hook), (size_t __size));
  367. extern PTR EXFUN((*__realloc_hook), (PTR __ptr, size_t __size));
  368.  
  369. /* Activate a standard collection of debugging hooks.  */
  370. extern void EXFUN(mcheck, (void EXFUN((*func), (void))));
  371.  
  372. /* Statistics available to the user.  */
  373. struct mstats
  374.   {
  375.     size_t bytes_total;        /* Total size of the heap. */
  376.     size_t chunks_used;        /* Chunks allocated by the user. */
  377.     size_t bytes_used;        /* Byte total of user-allocated chunks. */
  378.     size_t chunks_free;        /* Chunks in the free list. */
  379.     size_t bytes_free;        /* Byte total of chunks in the free list. */
  380.   };
  381.  
  382. /* Pick up the current statistics. */
  383. extern struct mstats EXFUN(mstats, (NOARGS));
  384.  
  385. #endif /* malloc.h  */
  386.  
  387. /* DO NOT DELETE THIS LINE -- free.c INSERTED HERE. */
  388. /* Free a block of memory allocated by `malloc'.
  389.    Copyright 1990 Free Software Foundation
  390.           Written May 1989 by Mike Haertel.
  391.  
  392.    The author may be reached (Email) at the address mike@ai.mit.edu,
  393.    or (US mail) as Mike Haertel c/o Free Software Foundation.
  394.  
  395. This program is free software; you can redistribute it and/or modify
  396. it under the terms of the GNU General Public License as published by
  397. the Free Software Foundation; either version 2 of the License, or
  398. (at your option) any later version.
  399.  
  400. This program is distributed in the hope that it will be useful,
  401. but WITHOUT ANY WARRANTY; without even the implied warranty of
  402. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  403. GNU General Public License for more details.
  404.  
  405. You should have received a copy of the GNU General Public License
  406. along with this program; if not, write to the Free Software
  407. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  408.  
  409. #ifndef __ONEFILE
  410. #include "ansidecl.h"
  411. #include <stddef.h>
  412. #include <stdlib.h>
  413.  
  414. #define _MALLOC_INTERNAL
  415. #include "malloc.h"
  416. #endif /* __ONEFILE */
  417.  
  418. /* Debugging hook for free.  */
  419. void EXFUN((*__free_hook), (PTR __ptr));
  420.  
  421. /* Return memory to the heap.  Like free() but don't call a __free_hook
  422.    if there is one.  */
  423. void
  424. DEFUN(__free, (ptr), PTR ptr)
  425. {
  426.   int type;
  427.   size_t block, blocks;
  428.   register size_t i;
  429.   struct list *prev, *next;
  430.  
  431.   block = BLOCK(ptr);
  432.  
  433.   type = _heapinfo[block].busy.type;
  434.   switch (type)
  435.     {
  436.     case 0:
  437.       /* Get as many statistics as early as we can.  */
  438.       --_chunks_used;
  439.       _bytes_used -= _heapinfo[block].busy.info.size * BLOCKSIZE;
  440.       _bytes_free += _heapinfo[block].busy.info.size * BLOCKSIZE;
  441.  
  442.       /* Find the free cluster previous to this one in the free list.
  443.      Start searching at the last block referenced; this may benefit
  444.      programs with locality of allocation.  */
  445.       i = _heapindex;
  446.       if (i > block)
  447.     while (i > block)
  448.       i = _heapinfo[i].free.prev;
  449.       else
  450.     {
  451.       do
  452.         i = _heapinfo[i].free.next;
  453.       while (i > 0 && i < block);
  454.       i = _heapinfo[i].free.prev;
  455.     }
  456.  
  457.       /* Determine how to link this block into the free list.  */
  458.       if (block == i + _heapinfo[i].free.size)
  459.     {
  460.       /* Coalesce this block with its predecessor.  */
  461.       _heapinfo[i].free.size += _heapinfo[block].busy.info.size;
  462.       block = i;
  463.     }
  464.       else
  465.     {
  466.       /* Really link this block back into the free list.  */
  467.       _heapinfo[block].free.size = _heapinfo[block].busy.info.size;
  468.       _heapinfo[block].free.next = _heapinfo[i].free.next;
  469.       _heapinfo[block].free.prev = i;
  470.       _heapinfo[i].free.next = block;
  471.       _heapinfo[_heapinfo[block].free.next].free.prev = block;
  472.       ++_chunks_free;
  473.     }
  474.  
  475.       /* Now that the block is linked in, see if we can coalesce it
  476.      with its successor (by deleting its successor from the list
  477.      and adding in its size).  */
  478.       if (block + _heapinfo[block].free.size == _heapinfo[block].free.next)
  479.     {
  480.       _heapinfo[block].free.size
  481.         += _heapinfo[_heapinfo[block].free.next].free.size;
  482.       _heapinfo[block].free.next
  483.         = _heapinfo[_heapinfo[block].free.next].free.next;
  484.       _heapinfo[_heapinfo[block].free.next].free.prev = block;
  485.       --_chunks_free;
  486.     }
  487.  
  488.       /* Now see if we can return stuff to the system.  */
  489.       blocks = _heapinfo[block].free.size;
  490.       if (blocks >= FINAL_FREE_BLOCKS && block + blocks == _heaplimit
  491.       && (*__morecore)(0) == ADDRESS(block + blocks))
  492.     {
  493.       register size_t bytes = blocks * BLOCKSIZE;
  494.       _heaplimit -= blocks;
  495.       (*__morecore)(- bytes);
  496.       _heapinfo[_heapinfo[block].free.prev].free.next
  497.         = _heapinfo[block].free.next;
  498.       _heapinfo[_heapinfo[block].free.next].free.prev
  499.         = _heapinfo[block].free.prev;
  500.       block = _heapinfo[block].free.prev;
  501.       --_chunks_free;
  502.       _bytes_free -= bytes;
  503.     }
  504.  
  505.       /* Set the next search to begin at this block.  */
  506.       _heapindex = block;
  507.       break;
  508.  
  509.     default:
  510.       /* Do some of the statistics.  */
  511.       --_chunks_used;
  512.       _bytes_used -= 1 << type;
  513.       ++_chunks_free;
  514.       _bytes_free += 1 << type;
  515.  
  516.       /* Get the address of the first free fragment in this block.  */
  517.       prev = (struct list *) ((char *) ADDRESS(block) +
  518.                   (_heapinfo[block].busy.info.frag.first << type));
  519.  
  520.       if (_heapinfo[block].busy.info.frag.nfree == (BLOCKSIZE >> type) - 1)
  521.     {
  522.       /* If all fragments of this block are free, remove them
  523.          from the fragment list and free the whole block.  */
  524.       next = prev;
  525.       for (i = 1; i < BLOCKSIZE >> type; ++i)
  526.         next = next->next;
  527.       prev->prev->next = next;
  528.       if (next != NULL)
  529.         next->prev = prev->prev;
  530.       _heapinfo[block].busy.type = 0;
  531.       _heapinfo[block].busy.info.size = 1;
  532.  
  533.       /* Keep the statistics accurate.  */
  534.       ++_chunks_used;
  535.       _bytes_used += BLOCKSIZE;
  536.       _chunks_free -= BLOCKSIZE >> type;
  537.       _bytes_free -= BLOCKSIZE;
  538.  
  539.       free(ADDRESS(block));
  540.     }
  541.       else if (_heapinfo[block].busy.info.frag.nfree != 0)
  542.     {
  543.       /* If some fragments of this block are free, link this
  544.          fragment into the fragment list after the first free
  545.          fragment of this block. */
  546.       next = (struct list *) ptr;
  547.       next->next = prev->next;
  548.       next->prev = prev;
  549.       prev->next = next;
  550.       if (next->next != NULL)
  551.         next->next->prev = next;
  552.       ++_heapinfo[block].busy.info.frag.nfree;
  553.     }
  554.       else
  555.     {
  556.       /* No fragments of this block are free, so link this
  557.          fragment into the fragment list and announce that
  558.          it is the first free fragment of this block. */
  559.       prev = (struct list *) ptr;
  560.       _heapinfo[block].busy.info.frag.nfree = 1;
  561.       _heapinfo[block].busy.info.frag.first = (unsigned int)
  562.         (((char *) ptr - (char *) NULL) % BLOCKSIZE >> type);
  563.       prev->next = _fraghead[type].next;
  564.       prev->prev = &_fraghead[type];
  565.       prev->prev->next = prev;
  566.       if (prev->next != NULL)
  567.         prev->next->prev = prev;
  568.     }
  569.       break;
  570.     }
  571. }
  572.  
  573. /* Return memory to the heap.  */
  574. void
  575. DEFUN(free, (ptr), PTR ptr)
  576. {
  577.   if (ptr == NULL)
  578.     return;
  579.  
  580.   if (__free_hook != NULL)
  581.     (*__free_hook)(ptr);
  582.   else
  583.     __free (ptr);
  584. }
  585.  
  586. /* DO NOT DELETE THIS LINE -- malloc.c INSERTED HERE. */
  587. /* Memory allocator `malloc'.
  588.    Copyright 1990 Free Software Foundation
  589.           Written May 1989 by Mike Haertel.
  590.  
  591.    The author may be reached (Email) at the address mike@ai.mit.edu,
  592.    or (US mail) as Mike Haertel c/o Free Software Foundation.
  593.  
  594. This program is free software; you can redistribute it and/or modify
  595. it under the terms of the GNU General Public License as published by
  596. the Free Software Foundation; either version 2 of the License, or
  597. (at your option) any later version.
  598.  
  599. This program is distributed in the hope that it will be useful,
  600. but WITHOUT ANY WARRANTY; without even the implied warranty of
  601. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  602. GNU General Public License for more details.
  603.  
  604. You should have received a copy of the GNU General Public License
  605. along with this program; if not, write to the Free Software
  606. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  607.  
  608. #ifndef __ONEFILE
  609. #include "ansidecl.h"
  610. #include <stddef.h>
  611. #include <stdlib.h>
  612. #include <string.h>
  613.  
  614. #define _MALLOC_INTERNAL
  615. #include "malloc.h"
  616. #endif /* __ONEFILE */
  617.  
  618. /* How to really get more memory.  */
  619. PTR EXFUN((*__morecore), (ptrdiff_t __size)) = __default_morecore;
  620.  
  621. /* Debugging hook for `malloc'.  */
  622. PTR EXFUN((*__malloc_hook), (size_t __size));
  623.  
  624. /* Pointer to the base of the first block.  */
  625. char *_heapbase;
  626.  
  627. /* Block information table.  Allocated with align/__free (not malloc/free).  */
  628. malloc_info *_heapinfo;
  629.  
  630. /* Number of info entries.  */
  631. static size_t heapsize;
  632.  
  633. /* Search index in the info table.  */
  634. size_t _heapindex;
  635.  
  636. /* Limit of valid info table indices.  */
  637. size_t _heaplimit;
  638.  
  639. /* Free lists for each fragment size.  */
  640. struct list _fraghead[BLOCKLOG];
  641.  
  642. /* Instrumentation.  */
  643. size_t _chunks_used;
  644. size_t _bytes_used;
  645. size_t _chunks_free;
  646. size_t _bytes_free;
  647.  
  648. /* Are you experienced?  */
  649. int __malloc_initialized;
  650.  
  651. /* Aligned allocation.  */
  652. static PTR
  653. DEFUN(align, (size), size_t size)
  654. {
  655.   PTR result;
  656.   unsigned int adj;
  657.  
  658.   result = (*__morecore)(size);
  659.   adj = (unsigned int) ((char *) result - (char *) NULL) % BLOCKSIZE;
  660.   if (adj != 0)
  661.     {
  662.       adj = BLOCKSIZE - adj;
  663.       (void) (*__morecore)(adj);
  664.       result = (char *) result + adj;
  665.     }
  666.   return result;
  667. }
  668.  
  669. /* Set everything up and remember that we have.  */
  670. static int
  671. DEFUN_VOID(initialize)
  672. {
  673.   heapsize = HEAP / BLOCKSIZE;
  674.   _heapinfo = (malloc_info *) align(heapsize * sizeof(malloc_info));
  675.   if (_heapinfo == NULL)
  676.     return 0;
  677.   memset(_heapinfo, 0, heapsize * sizeof(malloc_info));
  678.   _heapinfo[0].free.size = 0;
  679.   _heapinfo[0].free.next = _heapinfo[0].free.prev = 0;
  680.   _heapindex = 0;
  681.   _heapbase = (char *) _heapinfo;
  682.   __malloc_initialized = 1;
  683.   return 1;
  684. }
  685.  
  686. /* Get neatly aligned memory, initializing or
  687.    growing the heap info table as necessary. */
  688. static PTR
  689. DEFUN(morecore, (size), size_t size)
  690. {
  691.   PTR result;
  692.   malloc_info *newinfo, *oldinfo;
  693.   size_t newsize;
  694.  
  695.   result = align(size);
  696.   if (result == NULL)
  697.     return NULL;
  698.  
  699.   /* Check if we need to grow the info table.  */
  700.   if (BLOCK((char *) result + size) > heapsize)
  701.     {
  702.       newsize = heapsize;
  703.       while (BLOCK((char *) result + size) > newsize)
  704.     newsize *= 2;
  705.       newinfo = (malloc_info *) align(newsize * sizeof(malloc_info));
  706.       if (newinfo == NULL)
  707.     {
  708.       (*__morecore)(- size);
  709.       return NULL;
  710.     }
  711.       memset(newinfo, 0, newsize * sizeof(malloc_info));
  712.       memcpy(newinfo, _heapinfo, heapsize * sizeof(malloc_info));
  713.       oldinfo = _heapinfo;
  714.       newinfo[BLOCK(oldinfo)].busy.type = 0;
  715.       newinfo[BLOCK(oldinfo)].busy.info.size
  716.     = BLOCKIFY(heapsize * sizeof(malloc_info));
  717.       _heapinfo = newinfo;
  718.       __free(oldinfo);
  719.       heapsize = newsize;
  720.     }
  721.  
  722.   _heaplimit = BLOCK((char *) result + size);
  723.   return result;
  724. }
  725.  
  726. /* Allocate memory from the heap.  */
  727. PTR
  728. DEFUN(malloc, (size), size_t size)
  729. {
  730.   PTR result;
  731.   size_t block, blocks, lastblocks, start;
  732.   register size_t i;
  733.   struct list *next;
  734.  
  735.   if (size == 0)
  736.     return NULL;
  737.  
  738.   if (__malloc_hook != NULL)
  739.     return (*__malloc_hook)(size);
  740.  
  741.   if (!__malloc_initialized)
  742.     if (!initialize())
  743.       return NULL;
  744.  
  745.   if (size < sizeof(struct list))
  746.     size = sizeof(struct list);
  747.  
  748.   /* Determine the allocation policy based on the request size.  */
  749.   if (size <= BLOCKSIZE / 2)
  750.     {
  751.       /* Small allocation to receive a fragment of a block.
  752.      Determine the logarithm to base two of the fragment size. */
  753.       register size_t log = 1;
  754.       --size;
  755.       while ((size /= 2) != 0)
  756.     ++log;
  757.  
  758.       /* Look in the fragment lists for a
  759.      free fragment of the desired size. */
  760.       next = _fraghead[log].next;
  761.       if (next != NULL)
  762.     {
  763.       /* There are free fragments of this size.
  764.          Pop a fragment out of the fragment list and return it.
  765.          Update the block's nfree and first counters. */
  766.       result = (PTR) next;
  767.       next->prev->next = next->next;
  768.       if (next->next != NULL)
  769.         next->next->prev = next->prev;
  770.       block = BLOCK(result);
  771.       if (--_heapinfo[block].busy.info.frag.nfree != 0)
  772.         _heapinfo[block].busy.info.frag.first = (unsigned int)
  773.           (((char *) next->next - (char *) NULL) % BLOCKSIZE) >> log;
  774.  
  775.       /* Update the statistics.  */
  776.       ++_chunks_used;
  777.       _bytes_used += 1 << log;
  778.       --_chunks_free;
  779.       _bytes_free -= 1 << log;
  780.     }
  781.       else
  782.     {
  783.       /* No free fragments of the desired size, so get a new block
  784.          and break it into fragments, returning the first.  */
  785.       result = malloc(BLOCKSIZE);
  786.       if (result == NULL)
  787.         return NULL;
  788.  
  789.       /* Link all fragments but the first into the free list.  */
  790.       for (i = 1; i < BLOCKSIZE >> log; ++i)
  791.         {
  792.           next = (struct list *) ((char *) result + (i << log));
  793.           next->next = _fraghead[log].next;
  794.           next->prev = &_fraghead[log];
  795.           next->prev->next = next;
  796.           if (next->next != NULL)
  797.         next->next->prev = next;
  798.         }
  799.  
  800.       /* Initialize the nfree and first counters for this block.  */
  801.       block = BLOCK(result);
  802.       _heapinfo[block].busy.type = log;
  803.       _heapinfo[block].busy.info.frag.nfree = i - 1;
  804.       _heapinfo[block].busy.info.frag.first = i - 1;
  805.  
  806.       _chunks_free += (BLOCKSIZE >> log) - 1;
  807.       _bytes_free += BLOCKSIZE - (1 << log);
  808.     }
  809.     }
  810.   else
  811.     {
  812.       /* Large allocation to receive one or more blocks.
  813.      Search the free list in a circle starting at the last place visited.
  814.      If we loop completely around without finding a large enough
  815.      space we will have to get more memory from the system.  */
  816.       blocks = BLOCKIFY(size);
  817.       start = block = MALLOC_SEARCH_START;
  818.       while (_heapinfo[block].free.size < blocks)
  819.     {
  820.       block = _heapinfo[block].free.next;
  821.       if (block == start)
  822.         {
  823.           /* Need to get more from the system.  Check to see if
  824.          the new core will be contiguous with the final free
  825.          block; if so we don't need to get as much.  */
  826.           block = _heapinfo[0].free.prev;
  827.           lastblocks = _heapinfo[block].free.size;
  828.           if (_heaplimit != 0 && block + lastblocks == _heaplimit &&
  829.           (*__morecore)(0) == ADDRESS(block + lastblocks) &&
  830.           (morecore((blocks - lastblocks) * BLOCKSIZE)) != NULL)
  831.         {
  832.           _heapinfo[block].free.size = blocks;
  833.           _bytes_free += (blocks - lastblocks) * BLOCKSIZE;
  834.           continue;
  835.         }
  836.           result = morecore(blocks * BLOCKSIZE);
  837.           if (result == NULL)
  838.         return NULL;
  839.           block = BLOCK(result);
  840.           _heapinfo[block].busy.type = 0;
  841.           _heapinfo[block].busy.info.size = blocks;
  842.           ++_chunks_used;
  843.           _bytes_used += blocks * BLOCKSIZE;
  844.           return result;
  845.         }
  846.     }
  847.  
  848.       /* At this point we have found a suitable free list entry.
  849.      Figure out how to remove what we need from the list. */
  850.       result = ADDRESS(block);
  851.       if (_heapinfo[block].free.size > blocks)
  852.     {
  853.       /* The block we found has a bit left over,
  854.          so relink the tail end back into the free list. */
  855.       _heapinfo[block + blocks].free.size
  856.         = _heapinfo[block].free.size - blocks;
  857.       _heapinfo[block + blocks].free.next
  858.         = _heapinfo[block].free.next;
  859.       _heapinfo[block + blocks].free.prev
  860.         = _heapinfo[block].free.prev;
  861.       _heapinfo[_heapinfo[block].free.prev].free.next
  862.         = _heapinfo[_heapinfo[block].free.next].free.prev
  863.           = _heapindex = block + blocks;
  864.     }
  865.       else
  866.     {
  867.       /* The block exactly matches our requirements,
  868.          so just remove it from the list. */
  869.       _heapinfo[_heapinfo[block].free.next].free.prev
  870.         = _heapinfo[block].free.prev;
  871.       _heapinfo[_heapinfo[block].free.prev].free.next
  872.         = _heapindex = _heapinfo[block].free.next;
  873.       --_chunks_free;
  874.     }
  875.  
  876.       _heapinfo[block].busy.type = 0;
  877.       _heapinfo[block].busy.info.size = blocks;
  878.       ++_chunks_used;
  879.       _bytes_used += blocks * BLOCKSIZE;
  880.       _bytes_free -= blocks * BLOCKSIZE;
  881.     }
  882.  
  883.   return result;
  884. }
  885.  
  886. /* DO NOT DELETE THIS LINE -- realloc.c INSERTED HERE. */
  887. /* Change the size of a block allocated by `malloc'.
  888.    Copyright 1990 Free Software Foundation
  889.           Written May 1989 by Mike Haertel.
  890.  
  891.    The author may be reached (Email) at the address mike@ai.mit.edu,
  892.    or (US mail) as Mike Haertel c/o Free Software Foundation.
  893.  
  894. This program is free software; you can redistribute it and/or modify
  895. it under the terms of the GNU General Public License as published by
  896. the Free Software Foundation; either version 2 of the License, or
  897. (at your option) any later version.
  898.  
  899. This program is distributed in the hope that it will be useful,
  900. but WITHOUT ANY WARRANTY; without even the implied warranty of
  901. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  902. GNU General Public License for more details.
  903.  
  904. You should have received a copy of the GNU General Public License
  905. along with this program; if not, write to the Free Software
  906. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  907.  
  908. #ifndef __ONEFILE
  909. #include "ansidecl.h"
  910. #include <stdlib.h>
  911. #include <string.h>
  912.  
  913. #define _MALLOC_INTERNAL
  914. #include "malloc.h"
  915. #endif /* __ONEFILE */
  916.  
  917. #define MIN(A, B) ((A) < (B) ? (A) : (B))
  918.  
  919. /* Debugging hook for realloc.  */
  920. PTR EXFUN((*__realloc_hook), (PTR __ptr, size_t __size));
  921.  
  922. /* Resize the given region to the new size, returning a pointer
  923.    to the (possibly moved) region.  This is optimized for speed;
  924.    some benchmarks seem to indicate that greater compactness is
  925.    achieved by unconditionally allocating and copying to a
  926.    new region.  This module has incestuous knowledge of the
  927.    internals of both free and malloc. */
  928. PTR
  929. DEFUN(realloc, (ptr, size), PTR ptr AND size_t size)
  930. {
  931.   PTR result;
  932.   int type;
  933.   size_t block, blocks, oldlimit;
  934.  
  935.   if (size == 0)
  936.     {
  937.       free(ptr);
  938.       return NULL;
  939.     }
  940.   else if (ptr == NULL)
  941.     return malloc(size);
  942.  
  943.   if (__realloc_hook != NULL)
  944.     return (*__realloc_hook)(ptr, size);
  945.  
  946.   block = BLOCK(ptr);
  947.  
  948.   type = _heapinfo[block].busy.type;
  949.   switch (type)
  950.     {
  951.     case 0:
  952.       /* Maybe reallocate a large block to a small fragment.  */
  953.       if (size <= BLOCKSIZE / 2)
  954.     {
  955.       result = malloc(size);
  956.       if (result != NULL)
  957.         {
  958.           memcpy(result, ptr, size);
  959.           free(ptr);
  960.           return result;
  961.         }
  962.     }
  963.  
  964.       /* The new size is a large allocation as well;
  965.      see if we can hold it in place. */
  966.       blocks = BLOCKIFY(size);
  967.       if (blocks < _heapinfo[block].busy.info.size)
  968.     {
  969.       /* The new size is smaller; return
  970.          excess memory to the free list. */
  971.       _heapinfo[block + blocks].busy.type = 0;
  972.       _heapinfo[block + blocks].busy.info.size
  973.         = _heapinfo[block].busy.info.size - blocks;
  974.       _heapinfo[block].busy.info.size = blocks;
  975.       free(ADDRESS(block + blocks));
  976.       result = ptr;
  977.     }
  978.       else if (blocks == _heapinfo[block].busy.info.size)
  979.     /* No size change necessary.  */
  980.     result = ptr;
  981.       else
  982.     {
  983.       /* Won't fit, so allocate a new region that will.
  984.          Free the old region first in case there is sufficient
  985.          adjacent free space to grow without moving. */
  986.       blocks = _heapinfo[block].busy.info.size;
  987.       /* Prevent free from actually returning memory to the system.  */
  988.       oldlimit = _heaplimit;
  989.       _heaplimit = 0;
  990.       free(ptr);
  991.       _heaplimit = oldlimit;
  992.       result = malloc(size);
  993.       if (result == NULL)
  994.         {
  995.           (void) malloc(blocks * BLOCKSIZE);
  996.           return NULL;
  997.         }
  998.       if (ptr != result)
  999.         memmove(result, ptr, blocks * BLOCKSIZE);
  1000.     }
  1001.       break;
  1002.  
  1003.     default:
  1004.       /* Old size is a fragment; type is logarithm
  1005.      to base two of the fragment size.  */
  1006.       if (size > 1 << (type - 1) && size <= 1 << type)
  1007.     /* The new size is the same kind of fragment.  */
  1008.     result = ptr;
  1009.       else
  1010.     {
  1011.       /* The new size is different; allocate a new space,
  1012.          and copy the lesser of the new size and the old. */
  1013.       result = malloc(size);
  1014.       if (result == NULL)
  1015.         return NULL;
  1016.       memcpy(result, ptr, MIN(size, 1 << type));
  1017.       free(ptr);
  1018.     }
  1019.       break;
  1020.     }
  1021.  
  1022.   return result;
  1023. }
  1024.  
  1025. /* DO NOT DELETE THIS LINE -- unix.c INSERTED HERE. */
  1026. /* unix.c - get more memory with a UNIX system call.
  1027.    Copyright 1990 Free Software Foundation
  1028.           Written May 1989 by Mike Haertel.
  1029.  
  1030.    The author may be reached (Email) at the address mike@ai.mit.edu,
  1031.    or (US mail) as Mike Haertel c/o Free Software Foundation.
  1032.  
  1033. This program is free software; you can redistribute it and/or modify
  1034. it under the terms of the GNU General Public License as published by
  1035. the Free Software Foundation; either version 2 of the License, or
  1036. (at your option) any later version.
  1037.  
  1038. This program is distributed in the hope that it will be useful,
  1039. but WITHOUT ANY WARRANTY; without even the implied warranty of
  1040. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1041. GNU General Public License for more details.
  1042.  
  1043. You should have received a copy of the GNU General Public License
  1044. along with this program; if not, write to the Free Software
  1045. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  1046.  
  1047. #ifndef __ONEFILE
  1048. #include "ansidecl.h"
  1049. #include <stddef.h>
  1050.  
  1051. #define _MALLOC_INTERNAL
  1052. #include "malloc.h"
  1053. #endif /* __ONEFILE */
  1054.  
  1055. extern PTR EXFUN(sbrk, (ptrdiff_t size));
  1056.  
  1057. PTR
  1058. DEFUN(__default_morecore, (size), ptrdiff_t size)
  1059. {
  1060.   PTR result;
  1061.  
  1062.   result = sbrk(size);
  1063.   if (result == (PTR) -1)
  1064.     return NULL;
  1065.   return result;
  1066. }
  1067.  
  1068. #define __getpagesize getpagesize
  1069. /* DO NOT DELETE THIS LINE -- valloc.c INSERTED HERE. */
  1070. /* Allocate memory on a page boundary.
  1071.    Copyright 1990 Free Software Foundation
  1072.           Written May 1989 by Mike Haertel.
  1073.  
  1074.    The author may be reached (Email) at the address mike@ai.mit.edu,
  1075.    or (US mail) as Mike Haertel c/o Free Software Foundation.
  1076.  
  1077. This program is free software; you can redistribute it and/or modify
  1078. it under the terms of the GNU General Public License as published by
  1079. the Free Software Foundation; either version 2 of the License, or
  1080. (at your option) any later version.
  1081.  
  1082. This program is distributed in the hope that it will be useful,
  1083. but WITHOUT ANY WARRANTY; without even the implied warranty of
  1084. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1085. GNU General Public License for more details.
  1086.  
  1087. You should have received a copy of the GNU General Public License
  1088. along with this program; if not, write to the Free Software
  1089. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  1090.  
  1091. #ifndef __ONEFILE
  1092. #include "ansidecl.h"
  1093. #include <stdlib.h>
  1094. #endif /* __ONEFILE */
  1095.  
  1096. #if 0
  1097. /* On SunOS 4.1.1, <sys/param.h> typedefs size_t, which is bad since
  1098.    we typedef it above.  Maybe it's better just to have people compile
  1099.    -Dgetpagesize()=4096.  */
  1100. /* Deal with page size.  */
  1101. #ifdef BSD
  1102. #ifndef BSD4_1
  1103. #define HAVE_GETPAGESIZE
  1104. #endif
  1105. #endif
  1106.  
  1107. #ifndef HAVE_GETPAGESIZE
  1108.  
  1109. #include <sys/param.h>
  1110.  
  1111. #if !defined (PAGESIZE)
  1112. #ifdef EXEC_PAGESIZE
  1113. #define PAGESIZE EXEC_PAGESIZE
  1114. #else
  1115. #ifdef NBPG
  1116. #define PAGESIZE NBPG * CLSIZE
  1117. #ifndef CLSIZE
  1118. #define CLSIZE 1
  1119. #endif /* no CLSIZE */
  1120. #else /* no NBPG */
  1121. #define PAGESIZE NBPC
  1122. #endif /* no NBPG */
  1123. #endif /* no EXEC_PAGESIZE */
  1124. #endif /* no PAGESIZE */
  1125.  
  1126. size_t
  1127. DEFUN_VOID(__getpagesize)
  1128. {
  1129.   return PAGESIZE;
  1130. }
  1131. #endif /* not HAVE_GETPAGESIZE */
  1132. #endif /* 0 */
  1133.  
  1134. extern size_t EXFUN(__getpagesize, (NOARGS));
  1135.  
  1136. static size_t pagesize;
  1137.  
  1138. PTR
  1139. DEFUN(valloc, (size), size_t size)
  1140. {
  1141.   PTR result;
  1142.   unsigned int adj;
  1143.  
  1144.   if (pagesize == 0)
  1145.     pagesize = __getpagesize();
  1146.  
  1147.   result = malloc(size + pagesize);
  1148.   if (result == NULL)
  1149.     return NULL;
  1150.   adj = (unsigned int) ((char *) result - (char *) NULL) % pagesize;
  1151.   if (adj != 0)
  1152.     result = (char *) result + pagesize - adj;
  1153.   return result;
  1154. }
  1155.